package com.cmwa.solution.sys.menu.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;

import com.cmwa.solution.base.comparator.NumberComparator;
import com.cmwa.solution.base.entity.Employee;
import com.cmwa.solution.base.entity.Page;
import com.cmwa.solution.base.entity.SearchParam;
import com.cmwa.solution.exception.RepositoryException;
import com.cmwa.solution.sys.client.Client;
import com.cmwa.solution.sys.client.ClientManager;
import com.cmwa.solution.sys.menu.dao.MenuDao;
import com.cmwa.solution.sys.menu.entity.MenuVo;
import com.cmwa.solution.sys.menu.service.MenuService;
import com.cmwa.solution.utils.Constant;
import com.cmwa.solution.utils.SQLUtil;
import com.cmwa.solution.utils.SessionUtils;

@Service
public class MenuServiceImpl implements MenuService {
	private String BUTTON_MENU_TYPE = "1";
	private String NORMAL_MENU_TYPE = "0";
	private String OTHER_MENU_TYPE = "2";
	@Resource
	private MenuDao menuDao;

	@Override
	public Page<MenuVo> menuListPage(SearchParam param) {

		Employee employee = SessionUtils.getEmployee();
		param.getSp().put("createId", employee.getID());
		List<MenuVo> items = menuDao.menuListPage(param);
		return Page.create(items, param.getStart(), param.getLimit(), param.getTotal());
	}

	@Override
	public void saveMenu(MenuVo menu) throws RepositoryException {
		if ("0".equals(menu.getParentId())) {
			menu.setParentId("0");
			menu.setLevel(0);
		} else {
			MenuVo parent = queryMenuById(menu.getParentId());
			menu.setLevel(parent.getLevel() + 1);
		}
		menuDao.saveMenu(menu);
	}

	public MenuVo queryMenuById(String menuId) {
		return menuDao.queryMenuById(menuId);
	}

	@Override
	public List<MenuVo> queryThreeLevelMenuList(String belongSystem) {
		return menuDao.queryThreeLevelMenuList(belongSystem);
	}

	@Override
	public List<MenuVo> queryAllMenu() {
		return menuDao.queryAllMenu();
	}

	@Override
	public Integer queryNextSequence() {
		return menuDao.queryNextSequence();
	}

	@Override
	public List<MenuVo> queryMatchMenuList(String menuNM) {
		return menuDao.queryMatchMenuList(menuNM);
	}

	@Override
	public boolean checkRepeatMenuNM(String menuNM, String menuId) {
		return menuDao.queryRepeatMenuNMCount(menuNM,menuId) > 0;
	}

	@Override
	public List<MenuVo> queryAllButtonMenuByMenuIds(String menuIds, String mType, String belongSystem) {
		String[] menuArrIds = menuIds.split(",");
		List<String> list = Arrays.asList(menuArrIds);
		String field = "M.PARENTID";
		return menuDao.queryAllButtonMenuByMenuIds(SQLUtil.buildOracleSQLIn(list, 1000, field), mType, belongSystem);
	}

	@Override
	public Map<String, MenuVo> queryAllRealMenu() {
		Map<String, MenuVo> allMenuMap = new HashMap<String, MenuVo>();
		List<MenuVo> list = queryAllMenu();
		for (MenuVo menuVo : list) {
			if (Constant.MENU_TYPE.equals(menuVo.getType())) {
				allMenuMap.put(menuVo.getMenuId(), menuVo);
			}
		}
		return allMenuMap;
	}

	@Override
	public void updateMenu(MenuVo menu) {
		// 更新级数
		MenuVo parent = queryMenuById(menu.getParentId());
		if (parent != null) {
			menu.setLevel(parent.getLevel() + 1);
		}else{
			menu.setLevel(0);
		}
		menuDao.updateMenu(menu);
	}

	@Override
	public boolean hasSubMenu(String parentId) {
		Integer count = menuDao.querySubMenuCount(parentId);
		if (count == null) {
			return false;
		}
		return count > 0;
	}

	@Override
	public void deleteMenuWithStatus(String menuId) {
		menuDao.deleteMenuWithStatus(menuId);
	}

	@Override
	public Page<MenuVo> buttonListPage(SearchParam param) {
		String menuId = (String) param.getSp().get("menuId");
		String mType = (String) param.getSp().get("mType");
		String belongSystem = (String) param.getSp().get("belongSystem");
		List<MenuVo> items = queryButtonListByMenuIds(menuId, mType, belongSystem);
		return Page.create(items, param.getStart(), param.getLimit(), items.size());
	}


	public List<MenuVo> queryButtonListByMenuIds(String menuIds, String mType, String belongSystem) {
		String[] menuArrIds = menuIds.split(",");
		List<String> list = Arrays.asList(menuArrIds);
		String field = "M.PARENTID";
		return menuDao.queryButtonListByMenuIds(SQLUtil.buildOracleSQLIn(list, 1000, field), mType, belongSystem);
	}

	@Override
	public MenuVo queryMenuByCode(String code) {
		return menuDao.queryMenuByCode(code);
	}

	@Override
	public boolean checkRepeatURL(String url, String menuId) {
		if (url != null && !"0".equals(url) && (url.indexOf(".do") != -1 || url.indexOf(".jsp") != -1)) {
			return menuDao.queryRepeatURL(url,menuId) > 0;
		}
		return false;
	}

	@Override
	public MenuVo queryMenuByUrl(String url) {
		return menuDao.queryMenuByUrl(url);
	}

	/**
	 * 根据当前用户所属数据角色（多个），查询所有关联的操作角色所拥有的操作权限
	 */
	@Override
	public List<MenuVo> queryMenuListByEmpAndOperRole(String empId) {
		return menuDao.queryMenuListByEmpAndOperRole(empId);
	}
	
	@Override
	public List<MenuVo> queryEmpDefaultSelectedButtonMenu(String empId) {
		return menuDao.queryEmpDefaultSelectedButtonMenu(empId);
	}

	@Override
	public List<MenuVo> queryOrmemberDefaultSelectedButtonMenu(String unionId) {
		String[] unionIds = unionId.split("-");
		return menuDao.queryOrmemberDefaultSelectedButtonMenu(unionIds[0], unionIds[1]);
	}
	
	@Override
	public List<String> queryMcodeByEmpIdAndMcode(String empId, String mCode) {
		return menuDao.queryMcodeByEmpIdAndMcode(empId, mCode);
	}
	
	@Override
	public Map<Integer, List<MenuVo>> buildMenuMap(Employee user) {
		Client client = ClientManager.getInstance().getClient();
		if (client == null) {
			return new HashMap<Integer, List<MenuVo>>();
		}
		if (client.getMenuMap() == null || client.getMenuMap().size() == 0) {
			Map<Integer, List<MenuVo>> menuMap = new HashMap<Integer, List<MenuVo>>();
			Map<String, MenuVo> loginMenuMap = getCurrentUserMenu(user);
			// 操作按钮菜单
			Map<String, MenuVo> buttonMenuMap = new HashMap<String, MenuVo>();
			Map<String, MenuVo> otherMenus = new HashMap<String, MenuVo>();
			if (loginMenuMap.size() > 0) {
				Collection<MenuVo> allMenus = loginMenuMap.values();
				for (MenuVo menu : allMenus) {
					if (BUTTON_MENU_TYPE.equals(menu.getType())) {
						buttonMenuMap.put(menu.getCode(), menu);
						// 如果为表单或者弹出 不显示在系统菜单里面
						continue;
					}else if (NORMAL_MENU_TYPE.equals(menu.getType())) {
						if (!menuMap.containsKey(menu.getLevel() + 0)) {
							menuMap.put(menu.getLevel() + 0, new ArrayList<MenuVo>());
						}
						// 构建完整的URL
						if (isVaildURL(menu.getUrl())) {
							menu.setUrl(menu.getUrl());
						}
						menuMap.get(menu.getLevel() + 0).add(menu);
					}else if (OTHER_MENU_TYPE.equals(menu.getType())) {
						otherMenus.put(menu.getCode(), menu);
					}
				}
				// 菜单栏排序
				Collection<List<MenuVo>> c = menuMap.values();
				for (List<MenuVo> list : c) {
					Collections.sort(list, new NumberComparator());
				}
			}
			// 加入操作按钮菜单缓存列表
			client.setButtonMenus(buttonMenuMap);
			// 加入菜单缓存列表
			client.setMenuMap(menuMap);
			client.setOtherMenus(otherMenus);
		}
		return client.getMenuMap();
	}
	
	@Override
	public Map<String, MenuVo> getCurrentUserMenu(Employee user) {
		Client client = ClientManager.getInstance().getClient();
		if (client.getMenus() == null || client.getMenus().size() == 0) {
			Map<String, MenuVo> loginMenuMap = new HashMap<String, MenuVo>();
			Map<String, MenuVo> allMenu = queryAllRealMenu();
			// 查询当前登录用户所拥有的权限
			List<MenuVo> empMenuList = queryMenuListByEmpAndOperRole(user.getID());
			// 构建当前员工A的菜单数据
			for (MenuVo menuVo : empMenuList) {
				buildAssociatedMenu(allMenu, loginMenuMap, menuVo);
			}
			// 加入菜单缓存列表
			client.setMenus(loginMenuMap);
		}
		return client.getMenus();
	}
	
	@Override
	public void buildAssociatedMenu(Map<String, MenuVo> allMenu, Map<String, MenuVo> loginMenuList, MenuVo menuVo) {
		associatedMenu(allMenu, loginMenuList, menuVo);
		loginMenuList.put(menuVo.getMenuId(), menuVo);
	}

	@Override
	public void associatedMenu(Map<String, MenuVo> allMenu, Map<String, MenuVo> loginMenuList, MenuVo menuVo) {
		if (allMenu.containsKey(menuVo.getParentId())) {
			MenuVo menu = allMenu.get(menuVo.getParentId());
			loginMenuList.put(menu.getMenuId(), menu);
			associatedMenu(allMenu, loginMenuList, menu);
		} else {
			return;
		}
	}
	
	@Override
	public boolean isVaildURL(String url) {
		if (StringUtils.isNotBlank(url) && !"0".equals(url)) {
			return true;
		}
		return false;
	}
	
	@Override
	public List<String> queryAuthMenuByEmpId(@Param("empId") String empId){
		return menuDao.queryAuthMenuByEmpId(empId);
	}
}
